using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace EuropeEngulfed.NET
{
    [System.ComponentModel.DesignerCategory("")]
    class MapControl : Control
    {
        private const float ZOOM2SCALE = 0.5F;
        private const float ZOOM1SCALE = 0.75F;
        private const float BEZIERCURVATURE = 0.3F;
        private const int DEPLOY_START_POINT_X = 5;
        private const int DEPLOY_START_POINT_Y = 5;
        private const int DEPLOY_START_POINT_GAP = 10;
        private EuropeEngulfedColourMappedUIImage europeEngulfedMapImage;
        private System.Drawing.Drawing2D.Matrix europeEngulfedMapTransform;
        private scaleLevel currentScaleLevel;
        private int currentHScroll;
        private int currentVScroll;
        private IGameStateInfoProvider gameStateInfo;
        public enum scaleLevel { ZoomOut3 ,ZoomOut2, ZoomOut1, Normal };
        private bool hideAxisBlocks;
        private bool hideAlliedBlocks;
        public enum blockHighlightType { None, Allied, Axis, Centre };
        private blockHighlightType blockHighlight;
        private MapInfo.RegionID blockHilightRegionID;
        private bool hideMap;
        private bool calculatingSupply = false;
        public enum displayMode {Normal, AxisProduction, AlliedProduction, OperationalMovement, AlliedStratMove, AxisStratMove, DeployNewCountry, AxisInitialCombatPhase, AlliedInitialCombatPhase};
        private displayMode currentDisplayMode;
        private List<OperationalMove> listOfInitialOpsMoves;
        private List<PlayingPiece> listOfPlayingPiecesToDeploy;
        private List<Point> listPointsAtWhichPlayingPiecesToDeployAreShown;
        public enum fadingMessageType { rules, networkmessage };
        private struct FadingMessage
        {
            public string message;
            public int fadingMessageAlpha;
            public fadingMessageType messageType;
            public FadingMessage(string message, int fadingMessageAlpha, fadingMessageType messageType)
            {
                this.message = message;
                this.fadingMessageAlpha = fadingMessageAlpha;
                this.messageType = messageType;
            }
        };
        private List<FadingMessage> fadingMessages;
        private Timer fadingMessageTimer;
        private Font fadingMessageFont = new Font("Century Gothic", 10, FontStyle.Bold);
        private SolidBrush fadingMessageBrush;
        private int currentGermanWERPProduction = 0;
        private int currentItalianWERPProduction = 0;
        private int currentUKWERPProduction = 0;
        private int currentFrenchWERPProduction = 0;
        private int currentUSWERPProduction = 0;
        private int currentUSSRWERPProduction = 0;
        private int currentGermanSpecialActions = 0;
        private int currentItalianSpecialActions = 0;
        private int currentUKSpecialActions = 0;
        private int currentFrenchSpecialActions = 0;
        private int currentUSSpecialActions = 0;
        private int currentUSSRSpecialActions = 0;
        private int currentUSSREmergencyConscription = 0;
        private const int REMAININGWERPS_DISPLAY_Y1 = 30;
        private const int REMAININGWERPS_DISPLAY_Y2 = 90;
        private Bitmap battleIcon;
        private Bitmap battleDoneIcon;
        private struct FleetPointLocations
        {
            public Point location;
            public FleetPoint fleetPoint;
            public FleetPointLocations(Point location, FleetPoint fleetPoint)
            {
                this.location = location;
                this.fleetPoint = fleetPoint;
            }
        };
        List<FleetPointLocations> fleetPointLocations;
        /////////////////////////

        private void setDrawingMatrix()
        {
            europeEngulfedMapTransform.Reset();
            switch (currentScaleLevel)
            {
                case scaleLevel.ZoomOut3:
                    float ZOOM3SCALE = 0.25F;
                    float widthRatio = (float)this.Width / (float)europeEngulfedMapImage.MainImage.Size.Width;
                    float heightRatio = (float)this.Height / (float)europeEngulfedMapImage.MainImage.Size.Height;
                    if (widthRatio < heightRatio)
                        ZOOM3SCALE = widthRatio;
                    else
                        ZOOM3SCALE = heightRatio;
                    europeEngulfedMapTransform.Scale(widthRatio, heightRatio);
                    currentHScroll = 0;
                    currentVScroll = 0;
                    break;
                case scaleLevel.ZoomOut2:
                    europeEngulfedMapTransform.Scale(ZOOM2SCALE, ZOOM2SCALE);
                    break;
                case scaleLevel.ZoomOut1:
                    europeEngulfedMapTransform.Scale(ZOOM1SCALE, ZOOM1SCALE);
                    break;
                case scaleLevel.Normal:
                    europeEngulfedMapTransform.Scale(1.0F, 1.0F);
                    break;
                default:
                    System.Diagnostics.Debug.Assert(false, "Unhandled scale level");
                    europeEngulfedMapTransform.Scale(1.0F, 1.0F);
                    break;
            }
            europeEngulfedMapTransform.Translate(currentHScroll * -1, currentVScroll * -1);
        }

        public bool CalculatingSupply
        {
            set
            {
                calculatingSupply = value;
            }
        }

        public bool HideMap
        {
            set
            {
                hideMap = value;
            }
        }

        public displayMode DisplayMode
        {
            get
            {
                return currentDisplayMode;
            }

            set
            {
                currentDisplayMode = value;
            }
        }

        public List<OperationalMove> ListOfOpsMoves
        {
            set
            {
                listOfInitialOpsMoves = value;
            }
        }

        public List<PlayingPiece> ListOfPlayingPiecesToDeploy
        {
            set
            {
                listOfPlayingPiecesToDeploy = value;
            }
        }

        public int HScroll
        {
            get
            {
                return currentHScroll;
            }

            set
            {
                if (value < 0)
                    currentHScroll = 0;
                else if (value > (europeEngulfedMapImage.MainImage.Width - this.Width))
                    currentHScroll = europeEngulfedMapImage.MainImage.Width - this.Width;
                else
                    currentHScroll = value;
                setDrawingMatrix();
            }
        }

        public int VScroll
        {
            get
            {
                return currentVScroll;
            }

            set
            {
                if (value < 0)
                    currentVScroll = 0;
                else if (value > (europeEngulfedMapImage.MainImage.Height - this.Height))
                    currentVScroll = europeEngulfedMapImage.MainImage.Height - this.Height;
                else
                    currentVScroll = value;
                setDrawingMatrix();
            }
        }

        public int EuropeEngulfedMapWidth
        {
            get
            {
                if (europeEngulfedMapImage.MainImage != null)
                            return europeEngulfedMapImage.MainImage.Width;
                else
                {
                    System.Diagnostics.Debug.Assert(false, "Europe Engulfed Map Image not set when width requested");
                    return 0;
                }
            }
        }

        public int EuropeEngulfedMapHeight
        {
            get
            {
                if (europeEngulfedMapImage.MainImage != null)
                            return europeEngulfedMapImage.MainImage.Height;
                else
                {
                    System.Diagnostics.Debug.Assert(false, "Europe Engulfed Map Image not set when height requested");
                    return 0;
                }
            }
        }

        public bool MaxZoomInLevel
        {
            get
            {
                int testMaxZoom;
                testMaxZoom = (int)currentScaleLevel;
                testMaxZoom++;
                return !Enum.IsDefined(typeof(scaleLevel),testMaxZoom);
            }
        }

        public bool MaxZoomOutLevel
        {
            get
            {
                int testMaxZoom;
                testMaxZoom = (int)currentScaleLevel;
                testMaxZoom--;
                return !Enum.IsDefined(typeof(scaleLevel), testMaxZoom);
            }
        }

        public scaleLevel ScaleLevel
        {
            get { return currentScaleLevel; }
            set 
            {
                if (Enum.IsDefined(typeof(scaleLevel), value))
                {
                    currentScaleLevel = value;
                    setDrawingMatrix();
                }
            }
        }

        public int CurrentGermanWERPs
        {
            get
            {
                return currentGermanWERPProduction;
            }

            set
            {
                currentGermanWERPProduction = value;
            }
        }

        public int CurrentItalianWERPs
        {
            get
            {
                return currentItalianWERPProduction;
            }

            set
            {
                currentItalianWERPProduction = value;
            }
        }

        public int CurrentUKWERPs
        {
            get
            {
                return currentUKWERPProduction;
            }

            set
            {
                currentUKWERPProduction = value;
            }
        }

        public int CurrentFrenchWERPs
        {
            get
            {
                return currentFrenchWERPProduction;
            }

            set
            {
                currentFrenchWERPProduction = value;
            }
        }

        public int CurrentUSWERPs
        {
            get
            {
                return currentUSWERPProduction;
            }

            set
            {
                currentUSWERPProduction = value;
            }
        }

        public int CurrentUSSRWERPs
        {
            get
            {
                return currentUSSRWERPProduction;
            }

            set
            {
                currentUSSRWERPProduction = value;
            }
        }

        public int CurrentGermanSA
        {
            get
            {
                return currentGermanSpecialActions;
            }

            set
            {
                currentGermanSpecialActions = value;
            }
        }

        public int CurrentItalianSA
        {
            get
            {
                return currentItalianSpecialActions;
            }

            set
            {
                currentItalianSpecialActions = value;
            }
        }

        public int CurrentUKSA
        {
            get
            {
                return currentUKSpecialActions;
            }

            set
            {
                currentUKSpecialActions = value;
            }
        }

        public int CurrentFrenchSA
        {
            get
            {
                return currentFrenchSpecialActions;
            }

            set
            {
                currentFrenchSpecialActions = value;
            }
        }

        public int CurrentUSSA
        {
            get
            {
                return currentUSSpecialActions;
            }

            set
            {
                currentUSSpecialActions = value;
            }
        }

        public int CurrentUSSRSA
        {
            get
            {
                return currentUSSRSpecialActions;
            }

            set
            {
                currentUSSRSpecialActions = value;
            }
        }

        public int CurrentUSSREmergencyConscription
        {
            get
            {
                return currentUSSREmergencyConscription;
            }

            set
            {
                currentUSSREmergencyConscription = value;
            }
        }

        public void AddFadingMessage(string message, fadingMessageType messageType)
        {
            fadingMessages.Add(new FadingMessage(message, 127, messageType));
            if(!this.fadingMessageTimer.Enabled)
                this.fadingMessageTimer.Start();
        }

        public MapControl()
        {
            System.Reflection.Assembly thisExe;
            thisExe = System.Reflection.Assembly.GetExecutingAssembly();
            System.IO.Stream file;
            file = thisExe.GetManifestResourceStream("EuropeEngulfed.NET.Resources.battleicon.bmp");
            battleIcon = (Bitmap)Bitmap.FromStream(file);
            battleIcon.MakeTransparent(System.Drawing.Color.White);
            file.Dispose();
            file = thisExe.GetManifestResourceStream("EuropeEngulfed.NET.Resources.battledone.bmp");
            battleDoneIcon = (Bitmap)Bitmap.FromStream(file);
            battleDoneIcon.MakeTransparent(System.Drawing.Color.White);
            file.Dispose();
            europeEngulfedMapImage = new EuropeEngulfedColourMappedUIImage();
            europeEngulfedMapTransform = new System.Drawing.Drawing2D.Matrix();
            currentScaleLevel = scaleLevel.Normal;
            this.hideAlliedBlocks = false;
            this.hideAxisBlocks = false;
            currentHScroll = 0;
            currentVScroll = 0;
            this.DoubleBuffered = true;
            blockHighlight = blockHighlightType.None;
            blockHilightRegionID = MapInfo.RegionID.Alexandria;
            hideMap = true;
            currentDisplayMode = displayMode.Normal;
            listPointsAtWhichPlayingPiecesToDeployAreShown = new List<Point>();
            fleetPointLocations = new List<FleetPointLocations>();
            fadingMessages = new List<FadingMessage>();
            fadingMessageBrush = new SolidBrush(Color.FromArgb(127, Color.DarkRed));
            fadingMessageTimer = new Timer();
            fadingMessageTimer.Tick += new EventHandler(fadingMessageTimer_Tick);
            fadingMessageTimer.Interval = 250;
        }

        public MapControl(Form form) : this()
        {
            if(form is IGameStateInfoProvider)
                this.gameStateInfo = (IGameStateInfoProvider)form;
        }

        public MapControl(IGameStateInfoProvider gameInfoProvider) : this()
        {
            this.gameStateInfo = gameInfoProvider;
        }

        private static bool IsFadingMessageFaded(FadingMessage fadingMessage)
        {
            if (fadingMessage.fadingMessageAlpha <= 0)
                return true;
            return false;
        }

        void fadingMessageTimer_Tick(object sender, EventArgs e)
        {
            List<FadingMessage> fadingMessagesToCopy = new List<FadingMessage>(fadingMessages);
            fadingMessages.Clear();
            for (int i = 0; i < fadingMessagesToCopy.Count; i++)
            {
                FadingMessage fadingMessageToAddBack = fadingMessagesToCopy[i];
                fadingMessageToAddBack.fadingMessageAlpha -= 2;
                fadingMessages.Add(fadingMessageToAddBack);
            }

            fadingMessages.RemoveAll(IsFadingMessageFaded);
            this.Invalidate();
            if (fadingMessages.Count <= 0)
                fadingMessageTimer.Stop();
        }

        public FleetPoint GetFleetPointAtMousePoint(ref MapInfo.RegionID seaRegion, Point mousePt)
        {
            if(IsMouseOverRegion(ref seaRegion, mousePt))
            {
                if(MapInfo.IsSeaRegion(seaRegion))
                {
                    System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
                    System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
                    clickTransform.Invert();
                    clickTransform.TransformPoints(mousePoint);
                    foreach(FleetPointLocations fleetLocation in fleetPointLocations)
                    {
                        Rectangle rectToCheck = new Rectangle(fleetLocation.location.X - PlayingPieceGraphics.GetFleetSize().Width / 2, fleetLocation.location.Y - PlayingPieceGraphics.GetFleetSize().Height / 2, PlayingPieceGraphics.GetFleetSize().Width, PlayingPieceGraphics.GetFleetSize().Height);
                        if (rectToCheck.Contains(mousePoint[0]))
                        {
                            return fleetLocation.fleetPoint;
                        }
                    }
                }
            }

            return null;
        }

        public bool IsMouseOverCentreBlocks(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverCentredBlocks(ref regionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize());
        }

        public bool IsMouseOverContestedBlocks1(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverContestedBlocks1(ref regionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize());
        }

        public bool IsMouseOverContestedBlocks2(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverContestedBlocks2(ref regionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize());
        }

        public bool IsMouseOverRegion(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverRegion(ref regionID, mousePoint[0]);
        }

        public bool IsMouseOverCentredGSU(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverCentredGSU(ref regionID, mousePoint[0], PlayingPieceGraphics.GetGSUSize());
        }

        public bool IsMouseOverContestedGSU1(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverContestedGSU1(ref regionID, mousePoint[0], PlayingPieceGraphics.GetGSUSize());
        }

        public bool IsMouseOverContestedGSU2(ref MapInfo.RegionID regionID, Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            return this.europeEngulfedMapImage.IsMouseOverContestedGSU2(ref regionID, mousePoint[0], PlayingPieceGraphics.GetGSUSize());
        }

        public List<GroundSupportUnit> GetGSUListAtMousePoint(Point mousePt, ref int GSUIndex, ref MapInfo.RegionID regionID)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            if (this.europeEngulfedMapImage.IsMouseOverCentredGSU(ref regionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize()))
            {
                UIRegion uiRegion = europeEngulfedMapImage.GetUIRegion(regionID);
                List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(regionID);
                List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(regionID);
                List<GroundSupportUnit> alliedGSUList = gameStateInfo.GetRegionsAlliedGSUList(regionID);
                List<GroundSupportUnit> axisGSUList = gameStateInfo.GetRegionsAxisGSUList(regionID);
                if (axisBlockList.Count == 0 || alliedBlockList.Count == 0)
                {
                    if (alliedBlockList.Count > 0 && alliedBlockList.Count != 2)
                    {
                        GSUIndex = uiRegion.AlliedGSUIndex;
                        if (GSUIndex >= alliedGSUList.Count)
                            GSUIndex = alliedGSUList.Count - 1;
                        else if (GSUIndex < 0)
                            GSUIndex = 0;
                        return alliedGSUList;
                    }
                    else if (axisBlockList.Count > 0 && axisBlockList.Count != 2)
                    {
                        GSUIndex = uiRegion.AxisGSUIndex;
                        if (GSUIndex >= axisGSUList.Count)
                            GSUIndex = axisGSUList.Count - 1;
                        else if (GSUIndex < 0)
                            GSUIndex = 0;
                        return axisGSUList;
                    }
                    else if(axisBlockList.Count == 0 && alliedBlockList.Count == 0)
                    {
                        if(alliedGSUList.Count == 0 && axisGSUList.Count != 0)
                        {
                            GSUIndex = uiRegion.AxisGSUIndex;
                            if (GSUIndex >= axisGSUList.Count)
                                GSUIndex = axisGSUList.Count - 1;
                            else if (GSUIndex < 0)
                                GSUIndex = 0;
                            return axisGSUList;
                        }
                        else if(axisGSUList.Count == 0 && alliedGSUList.Count != 0)
                        {
                            GSUIndex = uiRegion.AlliedGSUIndex;
                            if (GSUIndex >= alliedGSUList.Count)
                                GSUIndex = alliedGSUList.Count - 1;
                            else if (GSUIndex < 0)
                                GSUIndex = 0;
                            return alliedGSUList;
                        }
                    }
                }
            }

            if (this.europeEngulfedMapImage.IsMouseOverContestedGSU1(ref regionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize()))
            {
                UIRegion uiRegion = europeEngulfedMapImage.GetUIRegion(regionID);
                List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(regionID);
                List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(regionID);
                List<GroundSupportUnit> alliedGSUList = gameStateInfo.GetRegionsAlliedGSUList(regionID);
                List<GroundSupportUnit> axisGSUList = gameStateInfo.GetRegionsAxisGSUList(regionID);
                if (alliedBlockList.Count > 0)
                {
                    if (axisBlockList.Count > 0 || alliedBlockList.Count == 2)
                    {
                        if (alliedBlockList.Count == 2 && axisBlockList.Count == 0)
                        {
                            GSUIndex = uiRegion.AlliedGSUIndex;
                            if (GSUIndex >= alliedGSUList.Count)
                                GSUIndex = alliedGSUList.Count - 1;
                            else if (GSUIndex < 0)
                                GSUIndex = 0;
                            return alliedGSUList;
                        }
                        else
                        {
                            GSUIndex = uiRegion.AlliedGSUIndex;
                            if (GSUIndex >= alliedGSUList.Count)
                                GSUIndex = alliedGSUList.Count - 1;
                            else if (GSUIndex < 0)
                                GSUIndex = 0;
                            return alliedGSUList;
                        }
                    }
                }
                else if(axisBlockList.Count > 0 && alliedBlockList.Count == 0)
                {
                    GSUIndex = uiRegion.AlliedGSUIndex;
                    if (GSUIndex >= alliedGSUList.Count)
                        GSUIndex = alliedGSUList.Count - 1;
                    else if (GSUIndex < 0)
                        GSUIndex = 0;
                    return alliedGSUList;
                }
            }
            else if (this.europeEngulfedMapImage.IsMouseOverContestedGSU2(ref regionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize()))
            {
                UIRegion uiRegion = europeEngulfedMapImage.GetUIRegion(regionID);
                List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(regionID);
                List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(regionID);
                List<GroundSupportUnit> alliedGSUList = gameStateInfo.GetRegionsAlliedGSUList(regionID);
                List<GroundSupportUnit> axisGSUList = gameStateInfo.GetRegionsAxisGSUList(regionID);
                if (axisBlockList.Count > 0)
                {
                    if (alliedBlockList.Count > 0 || axisBlockList.Count == 2)
                    {
                        if (axisBlockList.Count == 2 && alliedBlockList.Count == 0)
                        {
                            GSUIndex = uiRegion.AxisGSUIndex;
                            if (GSUIndex >= axisGSUList.Count)
                                GSUIndex = axisGSUList.Count - 1;
                            else if (GSUIndex < 0)
                                GSUIndex = 0;
                            return axisGSUList;
                        }
                        else
                        {
                            GSUIndex = uiRegion.AxisGSUIndex;
                            if (GSUIndex >= axisGSUList.Count)
                                GSUIndex = axisGSUList.Count - 1;
                            else if (GSUIndex < 0)
                                GSUIndex = 0;
                            return axisGSUList;
                        }
                    }
                }
                else if (alliedBlockList.Count > 0 && alliedBlockList.Count == 0)
                {
                    GSUIndex = uiRegion.AxisGSUIndex;
                    if (GSUIndex >= axisGSUList.Count)
                        GSUIndex = axisGSUList.Count - 1;
                    else if (GSUIndex < 0)
                        GSUIndex = 0;
                    return axisGSUList;
                }
            }
            return null;
        }

        public Point GetTransformedPoint(Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);

            return mousePoint[0];
        }

        public List<Block> GetBlockListAtMousePoint(Point mousePt, ref bool hideBlocks, ref int blockIndex, ref MapInfo.RegionID regionID)
        {
            return GetBlockListAtTransformedMousePoint(GetTransformedPoint(mousePt), ref hideBlocks, ref blockIndex, ref regionID);
        }

        public List<Block> GetBlockListAtTransformedMousePoint(Point mousePt, ref bool hideBlocks, ref int blockIndex, ref MapInfo.RegionID regionID)
        {
            hideBlocks = false;
            if (this.europeEngulfedMapImage.IsMouseOverCentredBlocks(ref regionID, mousePt, PlayingPieceGraphics.GetBlockSize()))
            {
                UIRegion uiRegion = europeEngulfedMapImage.GetUIRegion(regionID);
                List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(regionID);
                List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(regionID);
                if (axisBlockList.Count == 0 || alliedBlockList.Count == 0)
                {
                    if (alliedBlockList.Count > 0 && alliedBlockList.Count != 2)
                    {
                        if (hideAlliedBlocks)
                            hideBlocks = true;
                        blockIndex = uiRegion.CentredBlockIndex;
                        if (blockIndex >= alliedBlockList.Count)
                            blockIndex = alliedBlockList.Count - 1;
                        else if (blockIndex < 0)
                            blockIndex = 0;
                        return alliedBlockList;
                    }
                    else if (axisBlockList.Count > 0 && axisBlockList.Count != 2)
                    {
                        if (hideAxisBlocks)
                            hideBlocks = true;
                        blockIndex = uiRegion.CentredBlockIndex;
                        if (blockIndex >= axisBlockList.Count)
                            blockIndex = axisBlockList.Count - 1;
                        else if (blockIndex < 0)
                            blockIndex = 0;
                        return axisBlockList;
                    }
                }
            }

            if (this.europeEngulfedMapImage.IsMouseOverContestedBlocks1(ref regionID, mousePt, PlayingPieceGraphics.GetBlockSize()))
            {
                UIRegion uiRegion = europeEngulfedMapImage.GetUIRegion(regionID);
                List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(regionID);
                List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(regionID);
                if(alliedBlockList.Count > 0)
                {
                    if (axisBlockList.Count > 0 || alliedBlockList.Count == 2)
                    {
                        if (alliedBlockList.Count == 2 && axisBlockList.Count == 0)
                        {
                            if (hideAlliedBlocks)
                                hideBlocks = true;
                            List<Block> blockList = new List<Block>();
                            blockList.Add(alliedBlockList[0]);
                            blockIndex = 0;
                            return blockList;
                        }
                        else
                        {
                            if (hideAlliedBlocks && gameStateInfo.IsNewBattle(regionID))
                                hideBlocks = true;
                            blockIndex = uiRegion.AlliedBlockIndex;
                            if (blockIndex >= alliedBlockList.Count)
                                blockIndex = alliedBlockList.Count - 1;
                            else if(blockIndex < 0)
                                blockIndex = 0;
                            return alliedBlockList;
                        }
                    }
                }
                else if(axisBlockList.Count == 2)
                {
                    if (hideAxisBlocks)
                        hideBlocks = true;
                    List<Block> blockList = new List<Block>();
                    blockList.Add(axisBlockList[0]);
                    blockIndex = 0;
                    return blockList;
                }
            }
            else if (this.europeEngulfedMapImage.IsMouseOverContestedBlocks2(ref regionID, mousePt, PlayingPieceGraphics.GetBlockSize()))
            {
                UIRegion uiRegion = europeEngulfedMapImage.GetUIRegion(regionID);
                List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(regionID);
                List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(regionID);
                if (axisBlockList.Count > 0)
                {
                    if (alliedBlockList.Count > 0 || axisBlockList.Count == 2)
                    {
                        if (axisBlockList.Count == 2 && alliedBlockList.Count == 0)
                        {
                            if (hideAxisBlocks)
                                hideBlocks = true;
                            List<Block> blockList = new List<Block>();
                            blockList.Add(axisBlockList[1]);
                            blockIndex = 0;
                            return blockList;
                        }
                        else
                        {
                            if (hideAxisBlocks && gameStateInfo.IsNewBattle(regionID))
                                hideBlocks = true;
                            blockIndex = uiRegion.AxisBlockIndex;
                            if (blockIndex >= axisBlockList.Count)
                                blockIndex = axisBlockList.Count - 1;
                            else if (blockIndex < 0)
                                blockIndex = 0;
                            return axisBlockList;
                        }
                    }
                }
                else if (alliedBlockList.Count == 2)
                {
                    if (hideAlliedBlocks)
                        hideBlocks = true;
                    List<Block> blockList = new List<Block>();
                    blockList.Add(alliedBlockList[1]);
                    blockIndex = 0;
                    return blockList;
                }
            }
            return null;
        }

        public PlayingPiece GetPlayingPieceToDeployAtMousePoint(Point mousePt)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mousePt.X, mousePt.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);

            for (int i = 0; i < listPointsAtWhichPlayingPiecesToDeployAreShown.Count; i++)
            {
                Point ptToCheck = listPointsAtWhichPlayingPiecesToDeployAreShown[i];
                Rectangle blockRect = new Rectangle(ptToCheck.X + currentHScroll, ptToCheck.Y + currentVScroll, PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                if (blockRect.Contains(mousePoint[0]))
                {
                    return this.listOfPlayingPiecesToDeploy[i];
                }
            }

            return null;
        }

        public void HideAxisBlocks()
        {
            hideAxisBlocks = true;
        }

        public void HideAlliedBlocks()
        {
            hideAlliedBlocks = true;
        }

        public void ShowAxisBlocks()
        {
            hideAxisBlocks = false;
        }

        public void ShowAlliedBlocks()
        {
            hideAlliedBlocks = false;
        }

        private void DrawGSUList(Graphics g,List<GroundSupportUnit> GSUList,Point ptToDrawAt,int index)
        {
            if (GSUList.Count > 0)
            {
                if (GSUList.Count == 1)
                    PlayingPieceGraphics.PaintGSU(g, GSUList[0], ptToDrawAt);
                else
                {
                    int GSUIndex = index;
                    Point nextGSUPoint = ptToDrawAt;
                    do
                    {
                        GSUIndex++;
                        GSUIndex = GSUIndex % GSUList.Count;
                        PlayingPieceGraphics.PaintGSU(g, GSUList[GSUIndex], nextGSUPoint);
                        nextGSUPoint.X += PlayingPieceGraphics.GSUStackIncrement;
                        nextGSUPoint.Y += PlayingPieceGraphics.GSUStackIncrement;
                    }
                    while (GSUIndex != index);
                }
            }
        }

        private void GetNextPointToDrawInfoTrackMarkerAt(ref int pointOffset, ref Point ptToDrawAt, Rectangle infoTrackRect)
        {
            ptToDrawAt.X += PlayingPieceGraphics.GetMarkerSize().Width + pointOffset;
            if (!infoTrackRect.Contains(ptToDrawAt))
            {
                ptToDrawAt.X = infoTrackRect.X + PlayingPieceGraphics.GetMarkerSize().Width / 2 + pointOffset;
                ptToDrawAt.Y += PlayingPieceGraphics.GetMarkerSize().Height + pointOffset;
                if (!infoTrackRect.Contains(ptToDrawAt))
                {
                    pointOffset += 5;
                    ptToDrawAt.X = infoTrackRect.X + PlayingPieceGraphics.GetMarkerSize().Width / 2 + pointOffset;
                    ptToDrawAt.Y = infoTrackRect.Y + PlayingPieceGraphics.GetMarkerSize().Height / 2 + pointOffset;
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (hideMap)
                e.Graphics.Clear(System.Drawing.Color.Black);
            else
            {
                e.Graphics.Transform = europeEngulfedMapTransform;
                e.Graphics.DrawImage(europeEngulfedMapImage.MainImage, 0, 0);

                #region Calculating Supply
                if (calculatingSupply)
                {
                    Font supplyTextFont = new Font("Arial", 50);
                    e.Graphics.Transform = new System.Drawing.Drawing2D.Matrix();
                    e.Graphics.DrawString("Calculating Supply...", supplyTextFont, new SolidBrush(Color.Black), new PointF(this.Width / 2 - (e.Graphics.MeasureString("Calculating Supply...", supplyTextFont).Width / 2), this.Height / 2 - (e.Graphics.MeasureString("Calculating Supply...", supplyTextFont).Height / 2)));
                    e.Graphics.Transform = europeEngulfedMapTransform;
                }
                #endregion

                #region Draw blocks and Control Markers and Field Fortifications
                for (int i = 0; europeEngulfedMapImage.GetUIRegionAt(i) != null; i++)
                {
                    List<MapInfo.CountryID> countriesThatHaveSpentSA;
                    UIRegion uiRegionToPaint = europeEngulfedMapImage.GetUIRegionAt(i);
                    if (MapInfo.IsLandRegion((MapInfo.RegionID)uiRegionToPaint.RegionID))
                    {
                        #region Draw Field Fortifications
                        if(gameStateInfo.DoesRegionHaveFieldFortification((MapInfo.RegionID)uiRegionToPaint.RegionID))
                        {
                            PlayingPieceGraphics.PaintFieldFortification(e.Graphics,uiRegionToPaint.PointForFieldFortification);
                        }
                        else if(gameStateInfo.DoesRegionHaveHeavyFieldFortification((MapInfo.RegionID)uiRegionToPaint.RegionID))
                        {
                            PlayingPieceGraphics.PaintHeavyFieldFortification(e.Graphics, uiRegionToPaint.PointForFieldFortification);
                        }
                        #endregion

                        //******************************************
                        //TODO Implement extra block stack information
                        int axisBlockIndexToDraw = uiRegionToPaint.AxisBlockIndex;
                        int centredBlockIndexToDraw = uiRegionToPaint.CentredBlockIndex;
                        int alliedBlockIndexToDraw = uiRegionToPaint.AlliedBlockIndex;
                        int axisGSUIndexToDraw = uiRegionToPaint.AxisGSUIndex;
                        int alliedGSUIndexToDraw = uiRegionToPaint.AlliedGSUIndex;
                        List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList((MapInfo.RegionID)uiRegionToPaint.RegionID);
                        List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList((MapInfo.RegionID)uiRegionToPaint.RegionID);
                        List<GroundSupportUnit> alliedGSUList = gameStateInfo.GetRegionsAlliedGSUList((MapInfo.RegionID)uiRegionToPaint.RegionID);
                        List<GroundSupportUnit> axisGSUList = gameStateInfo.GetRegionsAxisGSUList((MapInfo.RegionID)uiRegionToPaint.RegionID);

                        #region Draw Beach Hide
                        if(gameStateInfo.RegionContainsABeachHead((MapInfo.RegionID)uiRegionToPaint.RegionID))
                        {
                            Region region = MapInfo.GetRegion((MapInfo.RegionID)uiRegionToPaint.RegionID);
                            if(region.IsLandRegion())
                            {
                                if (gameStateInfo.GetRegionBeachHeadCountry(region.RegionID) == MapInfo.CountryID.Germany)
                                {
                                    PlayingPieceGraphics.PaintAxisBeachHead(e.Graphics, uiRegionToPaint.PointForBeachHead);
                                }
                                else
                                {
                                    if(((LandRegion)region).WeatherZone == MapInfo.weatherZone.easternZone)
                                    {
                                        PlayingPieceGraphics.PaintSovietBeachHead(e.Graphics, uiRegionToPaint.PointForBeachHead);
                                    }
                                    else
                                        PlayingPieceGraphics.PaintWAlliesBeachHead(e.Graphics, uiRegionToPaint.PointForBeachHead);
                                }
                            }
                        }
                        #endregion

                        if (axisBlockIndexToDraw >= axisBlockList.Count)
                        {
                            axisBlockIndexToDraw = 0;
                            uiRegionToPaint.AxisBlockIndex = 0;
                        }
                        else if (axisBlockIndexToDraw < 0)
                        {
                            axisBlockIndexToDraw = axisBlockList.Count - 1;
                            uiRegionToPaint.AxisBlockIndex = axisBlockList.Count - 1;
                        }

                        if (alliedBlockIndexToDraw >= alliedBlockList.Count)
                        {
                            alliedBlockIndexToDraw = 0;
                            uiRegionToPaint.AlliedBlockIndex = 0;
                        }
                        else if (alliedBlockIndexToDraw < 0)
                        {
                            alliedBlockIndexToDraw = alliedBlockList.Count - 1;
                            uiRegionToPaint.AlliedBlockIndex = alliedBlockList.Count - 1;
                        }

                        if (axisGSUIndexToDraw >= axisGSUList.Count)
                        {
                            axisGSUIndexToDraw = 0;
                            uiRegionToPaint.AxisGSUIndex = 0;
                        }
                        else if (axisGSUIndexToDraw < 0)
                        {
                            axisGSUIndexToDraw = axisGSUList.Count - 1;
                            uiRegionToPaint.AxisGSUIndex = axisGSUList.Count - 1;
                        }

                        if (alliedGSUIndexToDraw >= alliedGSUList.Count)
                        {
                            alliedGSUIndexToDraw = 0;
                            uiRegionToPaint.AlliedGSUIndex = 0;
                        }
                        else if (alliedGSUIndexToDraw < 0)
                        {
                            alliedGSUIndexToDraw = alliedGSUList.Count - 1;
                            uiRegionToPaint.AlliedGSUIndex = alliedGSUList.Count - 1;
                        }

                        if (axisBlockList.Count > 0 && alliedBlockList.Count > 0)
                        {
                            if (gameStateInfo.IsNewBattle((MapInfo.RegionID)uiRegionToPaint.RegionID))
                            {
                                PlayingPieceGraphics.PaintBlock(e.Graphics, alliedBlockList[alliedBlockIndexToDraw], uiRegionToPaint.PointForContestedBlocks1, alliedBlockList.Count, hideAlliedBlocks);
                                PlayingPieceGraphics.PaintBlock(e.Graphics, axisBlockList[axisBlockIndexToDraw], uiRegionToPaint.PointForContestedBlocks2, axisBlockList.Count, hideAxisBlocks);
                            }
                            else
                            {
                                PlayingPieceGraphics.PaintBlock(e.Graphics, alliedBlockList[alliedBlockIndexToDraw], uiRegionToPaint.PointForContestedBlocks1, alliedBlockList.Count, false);
                                PlayingPieceGraphics.PaintBlock(e.Graphics, axisBlockList[axisBlockIndexToDraw], uiRegionToPaint.PointForContestedBlocks2, axisBlockList.Count, false);
                            }

                            DrawGSUList(e.Graphics, alliedGSUList, uiRegionToPaint.PointForContestedGSU1, alliedGSUIndexToDraw);
                            DrawGSUList(e.Graphics, axisGSUList, uiRegionToPaint.PointForContestedGSU2, axisGSUIndexToDraw);
                        }
                        else if (axisBlockList.Count > 0)
                        {
                            if (axisBlockList.Count <= 2) //Draw each unit side by side
                            {
                                if (axisBlockList.Count > 1)
                                {
                                    PlayingPieceGraphics.PaintBlock(e.Graphics, axisBlockList[0], uiRegionToPaint.PointForContestedBlocks1, 1, hideAxisBlocks);
                                    PlayingPieceGraphics.PaintBlock(e.Graphics, axisBlockList[1], uiRegionToPaint.PointForContestedBlocks2, 1, hideAxisBlocks);
                                    DrawGSUList(e.Graphics, axisGSUList, uiRegionToPaint.PointForContestedGSU2, axisGSUIndexToDraw);
                                }
                                else
                                {
                                    PlayingPieceGraphics.PaintBlock(e.Graphics, axisBlockList[0], uiRegionToPaint.PointForCentredBlocks, axisBlockList.Count, hideAxisBlocks);
                                    DrawGSUList(e.Graphics, axisGSUList, uiRegionToPaint.PointForCentredGSU, axisGSUIndexToDraw);
                                }
                            }
                            else
                            {
                                if (centredBlockIndexToDraw >= axisBlockList.Count)
                                {
                                    centredBlockIndexToDraw = 0;
                                    uiRegionToPaint.CentredBlockIndex = 0;
                                }
                                else if (centredBlockIndexToDraw < 0)
                                {
                                    centredBlockIndexToDraw = axisBlockList.Count - 1;
                                    uiRegionToPaint.CentredBlockIndex = axisBlockList.Count - 1;
                                }

                                PlayingPieceGraphics.PaintBlock(e.Graphics, axisBlockList[centredBlockIndexToDraw], uiRegionToPaint.PointForCentredBlocks, axisBlockList.Count, hideAxisBlocks);
                                DrawGSUList(e.Graphics, axisGSUList, uiRegionToPaint.PointForCentredGSU, axisGSUIndexToDraw);
                            }

                            DrawGSUList(e.Graphics, alliedGSUList, uiRegionToPaint.PointForContestedGSU1, alliedGSUIndexToDraw);
                        }
                        else if (alliedBlockList.Count > 0)
                        {
                            if (alliedBlockList.Count <= 2) //Draw each unit side by side
                            {
                                if (alliedBlockList.Count > 1)
                                {
                                    PlayingPieceGraphics.PaintBlock(e.Graphics, alliedBlockList[0], uiRegionToPaint.PointForContestedBlocks1, 1, hideAlliedBlocks);
                                    PlayingPieceGraphics.PaintBlock(e.Graphics, alliedBlockList[1], uiRegionToPaint.PointForContestedBlocks2, 1, hideAlliedBlocks);
                                    DrawGSUList(e.Graphics, alliedGSUList, uiRegionToPaint.PointForContestedGSU1, alliedGSUIndexToDraw);
                                }
                                else
                                {
                                    PlayingPieceGraphics.PaintBlock(e.Graphics, alliedBlockList[0], uiRegionToPaint.PointForCentredBlocks, alliedBlockList.Count, hideAlliedBlocks);
                                    DrawGSUList(e.Graphics, alliedGSUList, uiRegionToPaint.PointForCentredGSU, alliedGSUIndexToDraw);
                                }
                            }
                            else
                            {
                                if (centredBlockIndexToDraw >= alliedBlockList.Count)
                                {
                                    centredBlockIndexToDraw = 0;
                                    uiRegionToPaint.CentredBlockIndex = 0;
                                }
                                else if (centredBlockIndexToDraw < 0)
                                {
                                    centredBlockIndexToDraw = alliedBlockList.Count - 1;
                                    uiRegionToPaint.CentredBlockIndex = alliedBlockList.Count - 1;
                                }
                                PlayingPieceGraphics.PaintBlock(e.Graphics, alliedBlockList[centredBlockIndexToDraw], uiRegionToPaint.PointForCentredBlocks, alliedBlockList.Count, hideAlliedBlocks);
                                DrawGSUList(e.Graphics, alliedGSUList, uiRegionToPaint.PointForCentredGSU, alliedGSUIndexToDraw);
                            }

                            DrawGSUList(e.Graphics, axisGSUList, uiRegionToPaint.PointForContestedGSU2, axisGSUIndexToDraw);
                        }
                        else if(axisGSUList.Count > 0 && alliedGSUList.Count == 0)
                        {
                            DrawGSUList(e.Graphics, axisGSUList, uiRegionToPaint.PointForCentredGSU, axisGSUIndexToDraw);
                        }
                        else if(axisGSUList.Count == 0 && alliedGSUList.Count > 0)
                        {
                            DrawGSUList(e.Graphics, alliedGSUList, uiRegionToPaint.PointForCentredGSU, alliedGSUIndexToDraw);
                        }
                        else if(axisGSUList.Count > 0 && alliedGSUList.Count > 0)
                        {
                            DrawGSUList(e.Graphics, alliedGSUList,  uiRegionToPaint.PointForContestedGSU1, alliedGSUIndexToDraw);
                            DrawGSUList(e.Graphics, axisGSUList,    uiRegionToPaint.PointForContestedGSU2, axisGSUIndexToDraw);
                        }
                        else if (MapInfo.GetRegionOriginalCountryControl((MapInfo.RegionID)uiRegionToPaint.RegionID) != gameStateInfo.GetRegionControl((MapInfo.RegionID)uiRegionToPaint.RegionID))
                        {
                            MapInfo.CountryID country = gameStateInfo.GetRegionControl((MapInfo.RegionID)uiRegionToPaint.RegionID);
                            switch (country)
                            {
                                case MapInfo.CountryID.GreatBritain:
                                case MapInfo.CountryID.Germany:
                                case MapInfo.CountryID.USA:
                                case MapInfo.CountryID.USSR:
                                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, country, uiRegionToPaint.PointForCentredBlocks, false);
                                    break;
                                case MapInfo.CountryID.France:
                                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.GreatBritain, uiRegionToPaint.PointForCentredBlocks, false);
                                    break;
                                case MapInfo.CountryID.Italy:
                                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.Germany, uiRegionToPaint.PointForCentredBlocks, false);
                                    break;
                            }
                        }

                        if(currentDisplayMode == displayMode.AxisInitialCombatPhase || currentDisplayMode == displayMode.AlliedInitialCombatPhase)
                        {
                            if(gameStateInfo.IsBattleDone((MapInfo.RegionID)uiRegionToPaint.RegionID))
                                e.Graphics.DrawImage(battleDoneIcon, uiRegionToPaint.PointCentre.X - battleIcon.Width / 2, uiRegionToPaint.PointCentre.Y - battleIcon.Height / 2);
                            else if (gameStateInfo.IsNewBattle((MapInfo.RegionID)uiRegionToPaint.RegionID))
                                e.Graphics.DrawImage(battleIcon, uiRegionToPaint.PointCentre.X - battleIcon.Width / 2, uiRegionToPaint.PointCentre.Y - battleIcon.Height / 2);
                        }
                    }

                    #region Draw Mini Transparent Special Actions for Production Phase
                    if(currentDisplayMode == displayMode.AxisProduction || currentDisplayMode == displayMode.AlliedProduction)
                    {
                        Point ptToDrawAt = uiRegionToPaint.PointForCentredBlocks;
                        countriesThatHaveSpentSA = gameStateInfo.GetCountriesThatHaveSpentSAUnlimitedReplacement((MapInfo.RegionID)uiRegionToPaint.RegionID);
                        foreach (MapInfo.CountryID country in countriesThatHaveSpentSA)
                        {
                            PlayingPieceGraphics.PaintMiniTransparentSpecialActions(e.Graphics, country, ptToDrawAt);
                            ptToDrawAt.X += PlayingPieceGraphics.GetMiniTransparentSASize().Width;
                        }
                    }
                    else if (currentDisplayMode == displayMode.OperationalMovement || currentDisplayMode == displayMode.OperationalMovement)
                    {
                        Point ptToDrawAt = uiRegionToPaint.PointForCentredBlocks;
                        countriesThatHaveSpentSA = gameStateInfo.GetCountriesThatHaveSpentSARetreatFromCombatWithoutRearGuard((MapInfo.RegionID)uiRegionToPaint.RegionID);
                        foreach (MapInfo.CountryID country in countriesThatHaveSpentSA)
                        {
                            PlayingPieceGraphics.PaintMiniTransparentSpecialActions(e.Graphics, country, ptToDrawAt);
                            ptToDrawAt.X += PlayingPieceGraphics.GetMiniTransparentSASize().Width;
                        }
                    }
                    #endregion
                }
                #endregion

                #region Draw Fleet Points
                fleetPointLocations.Clear();
                List<FleetPoint> fleetPoints;
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.Germany, MapInfo.RegionID.BalticSea);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.BalticSea);
                    Point ptToDrawAt = uiSeaRegion.GermanfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.USSR, MapInfo.RegionID.BalticSea);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.BalticSea);
                    Point ptToDrawAt = uiSeaRegion.SovietfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.Germany, MapInfo.RegionID.AtlanticOcean);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.AtlanticOcean);
                    Point ptToDrawAt = uiSeaRegion.GermanfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.GreatBritain, MapInfo.RegionID.AtlanticOcean);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.AtlanticOcean);
                    Point ptToDrawAt = uiSeaRegion.BritishfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.France, MapInfo.RegionID.AtlanticOcean);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.AtlanticOcean);
                    Point ptToDrawAt = uiSeaRegion.FrenchfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.GreatBritain, MapInfo.RegionID.MediteraneanSea);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.MediteraneanSea);
                    Point ptToDrawAt = uiSeaRegion.BritishfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.France, MapInfo.RegionID.MediteraneanSea);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.MediteraneanSea);
                    Point ptToDrawAt = uiSeaRegion.FrenchfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.Italy, MapInfo.RegionID.MediteraneanSea);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.MediteraneanSea);
                    Point ptToDrawAt = uiSeaRegion.ItalianfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                fleetPoints = gameStateInfo.GetFleetPointList(MapInfo.CountryID.USSR, MapInfo.RegionID.BlackSea);
                if (fleetPoints.Count > 0)
                {
                    UISeaRegion uiSeaRegion = (UISeaRegion)europeEngulfedMapImage.GetUIRegion(MapInfo.RegionID.BlackSea);
                    Point ptToDrawAt = uiSeaRegion.SovietfleetDrawPoint;
                    for (int i = 0; i < fleetPoints.Count; i++)
                    {
                        Point actualPointDrawnAt = new Point(ptToDrawAt.X + (i % EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Width + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP), ptToDrawAt.Y + (i / EuropeEngulfedColourMappedUIImage.FLEET_POINT_ROWS) * (PlayingPieceGraphics.GetMarkerSize().Height + EuropeEngulfedColourMappedUIImage.FLEET_POINT_GAP));
                        PlayingPieceGraphics.PaintFleetPoint(e.Graphics, fleetPoints[i], actualPointDrawnAt);
                        fleetPointLocations.Add(new FleetPointLocations(actualPointDrawnAt, fleetPoints[i]));
                    }
                }
                #endregion

                #region Draw block highlight
                if (blockHighlight != blockHighlightType.None)
                {
                    UIRegion uiRegionToHighlightBlock = europeEngulfedMapImage.GetUIRegion(blockHilightRegionID);
                    if (uiRegionToHighlightBlock != null)
                    {
                        switch (blockHighlight)
                        {
                            case blockHighlightType.Allied:
                                e.Graphics.DrawRectangle(new Pen(System.Drawing.Color.Black, 3), uiRegionToHighlightBlock.PointForContestedBlocks1.X - PlayingPieceGraphics.GetBlockSize().Width / 2, uiRegionToHighlightBlock.PointForContestedBlocks1.Y - PlayingPieceGraphics.GetBlockSize().Height / 2, PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                                break;
                            case blockHighlightType.Axis:
                                e.Graphics.DrawRectangle(new Pen(System.Drawing.Color.Black, 3), uiRegionToHighlightBlock.PointForContestedBlocks2.X - PlayingPieceGraphics.GetBlockSize().Width / 2, uiRegionToHighlightBlock.PointForContestedBlocks2.Y - PlayingPieceGraphics.GetBlockSize().Height / 2, PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                                break;
                            case blockHighlightType.Centre:
                                e.Graphics.DrawRectangle(new Pen(System.Drawing.Color.Black, 3), uiRegionToHighlightBlock.PointForCentredBlocks.X - PlayingPieceGraphics.GetBlockSize().Width / 2, uiRegionToHighlightBlock.PointForCentredBlocks.Y - PlayingPieceGraphics.GetBlockSize().Height / 2, PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                                break;
                        }
                    }
                }
                #endregion

                #region Draw Information Track Counters
                //TODO Make info track tooltip (in case there are too many counters in a space)
                for (int i = 0; i <= 30; i++)
                {
                    int pointOffset = 0;
                    Rectangle infoTrackRect = this.europeEngulfedMapImage.GetInformationTrackRect(i);
                    Point ptToDrawAt = new Point(infoTrackRect.X - PlayingPieceGraphics.GetMarkerSize().Width / 2, infoTrackRect.Y + PlayingPieceGraphics.GetMarkerSize().Height / 2);
                    if (this.gameStateInfo.GetGermanUBoatPoints() == i || this.gameStateInfo.GetGermanUBoatPoints() == (i + 30))
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        if (this.gameStateInfo.GetGermanUBoatPoints() <= 30)
                            PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanUBoats, ptToDrawAt);
                        else
                            PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanUBoats30, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetGermanFlakLevel() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanFlak, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetGermanFighterPoints() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanFighter, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetGermanBomberPoints() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanBomber, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetGermanV1Points() == i && i > 0)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanV1, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetGermanV2Points() == i && i > 0)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.GermanV2, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetASWLevel() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.BritASW, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetWesternAlliedFlakLevel() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.BritishFlak, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetWesternAlliedFighterPoints() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.WAlliedFigtherPoints, ptToDrawAt);
                    }
                    if (this.gameStateInfo.GetWesternAlliedBomberPoints() == i)
                    {
                        GetNextPointToDrawInfoTrackMarkerAt(ref pointOffset, ref ptToDrawAt, infoTrackRect);
                        PlayingPieceGraphics.PaintInfoTrackMarker(e.Graphics, PlayingPieceGraphics.InfoTrackMarker.WAlliedBomberPoints, ptToDrawAt);
                    }
                }
                #endregion

                #region Draw Game Turn
                Point ptToDrawGameTurnMarkerAt = this.europeEngulfedMapImage.GetTurnMarkerPoint(this.gameStateInfo.GetCurrentGameDate());
                PlayingPieceGraphics.PaintTurnMarker(e.Graphics, ptToDrawGameTurnMarkerAt, this.gameStateInfo.GetCurrentGamePhase() == GameTurn.GamePhase.AlliedPlayerTurn);
                #endregion

                #region Draw Strategic Build Restriction Counters
                GameTurn.GameDate nextBritishFleetAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.GreatBritain);
                GameTurn.GameDate nextFrenchFleetAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.France);
                GameTurn.GameDate nextGermanFleetAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.Germany);
                GameTurn.GameDate nextItaFleetAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.Italy);
                GameTurn.GameDate nextUSFleetAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.USA);
                GameTurn.GameDate nextUSSRFleetAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.USSR);
                GameTurn.GameDate nextGermanFlakAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.Germany);
                GameTurn.GameDate nextBritishFlakAllowed = gameStateInfo.GetNextFleetAllowed(MapInfo.CountryID.GreatBritain);
                GameTurn.GameDate nextASWAllowed = gameStateInfo.GetNextASWAllowed();
                foreach (GameTurn.GameDate gameDate in Enum.GetValues(typeof(GameTurn.GameDate)))
                {
                    if(gameDate != GameTurn.GameDate.JanFeb46)
                    {
                        int markerHeight = PlayingPieceGraphics.GetBuildRestrictionMarkerSize().Height;
                        Point ptToRestrictionMarkerAtTurnMarkerAt = this.europeEngulfedMapImage.GetTurnMarkerPoint(gameDate);
                        if (gameDate == this.gameStateInfo.GetCurrentGameDate())
                        {
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }
                        if (gameDate == nextBritishFleetAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFleetAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.GreatBritain);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }
                        if (gameDate == nextFrenchFleetAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFleetAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.France);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }
                        if (gameDate == nextGermanFleetAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFleetAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.Germany);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }
                        if (gameDate == nextItaFleetAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFleetAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.Italy);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }
                        if (gameDate == nextUSFleetAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFleetAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.USA);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }
                        if (gameDate == nextUSSRFleetAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFleetAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.USSR);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }

                        if (gameDate == nextGermanFlakAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFlakAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.Germany);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }

                        if (gameDate == nextBritishFlakAllowed)
                        {
                            PlayingPieceGraphics.PaintNextFlakAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt, MapInfo.CountryID.GreatBritain);
                            ptToRestrictionMarkerAtTurnMarkerAt.Y -= markerHeight;
                        }

                        if (gameDate == nextASWAllowed)
                        {
                            PlayingPieceGraphics.PaintNextASWAllowed(e.Graphics, ptToRestrictionMarkerAtTurnMarkerAt);
                        }
                    }
                }
                #endregion

                #region Draw Weather Markers
                PlayingPieceGraphics.PaintWeatherMarker(e.Graphics, gameStateInfo.GetCurrentWesternWeather(), EuropeEngulfedColourMappedUIImage.westernWeatherMarkerPoint);
                PlayingPieceGraphics.PaintWeatherMarker(e.Graphics, gameStateInfo.GetCurrentEasternWeather(), EuropeEngulfedColourMappedUIImage.easternWeatherMarkerPoint);
                PlayingPieceGraphics.PaintWeatherMarker(e.Graphics, gameStateInfo.GetCurrentSouthernWeather(), EuropeEngulfedColourMappedUIImage.southernWeatherMarkerPoint);
                #endregion

                #region InitialOpsInformation
                if (currentDisplayMode == displayMode.OperationalMovement)
                {
                    foreach (OperationalMove initOpsMove in listOfInitialOpsMoves)
                    {
                        if (initOpsMove is MovePieceOperationalMove)
                        {
                            MovePieceOperationalMove moveInitOpsMove = (MovePieceOperationalMove)initOpsMove;
                            UIRegion uiRegionFrom = europeEngulfedMapImage.GetUIRegion(moveInitOpsMove.RegionMovedFrom);
                            UIRegion uiRegionTo = europeEngulfedMapImage.GetUIRegion(moveInitOpsMove.RegionMovedTo);
                            Point firstControlPoint;
                            Point secondControlPoint;
                            if (Math.Abs(uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) > Math.Abs(uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y))
                            {
                                firstControlPoint = new Point(uiRegionFrom.PointForCentredBlocks.X - ((uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) / 3), uiRegionFrom.PointForCentredBlocks.Y - ((uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y) / 3) + (int)(Math.Abs(uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) * BEZIERCURVATURE));
                                secondControlPoint = new Point(uiRegionFrom.PointForCentredBlocks.X - (((uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) / 3) * 2), uiRegionFrom.PointForCentredBlocks.Y - (((uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y) / 3) * 2) + (int)(Math.Abs(uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) * BEZIERCURVATURE));
                            }
                            else
                            {
                                firstControlPoint = new Point(uiRegionFrom.PointForCentredBlocks.X - ((uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) / 3) + (int)(Math.Abs(uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y) * BEZIERCURVATURE), uiRegionFrom.PointForCentredBlocks.Y - ((uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y) / 3));
                                secondControlPoint = new Point(uiRegionFrom.PointForCentredBlocks.X - (((uiRegionFrom.PointForCentredBlocks.X - uiRegionTo.PointForCentredBlocks.X) / 3) * 2) + (int)(Math.Abs(uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y) * BEZIERCURVATURE), uiRegionFrom.PointForCentredBlocks.Y - (((uiRegionFrom.PointForCentredBlocks.Y - uiRegionTo.PointForCentredBlocks.Y) / 3) * 2));
                            }
                            e.Graphics.DrawBezier(new Pen(Color.FromArgb(128, Color.Red), 10), uiRegionFrom.PointForCentredBlocks, firstControlPoint, secondControlPoint, uiRegionTo.PointForCentredBlocks);
                            //TODO Try out other curve functions (such as DrawArc) instead
                            //TODO Draw Arrowhead
                            //TODO Set curvature correctly for double move
                        }
                    }
                }
                #endregion

                #region Deploy Mode
                if(currentDisplayMode == displayMode.DeployNewCountry)
                {
                    listPointsAtWhichPlayingPiecesToDeployAreShown.Clear();
                    Point pointToDrawAt = new Point(DEPLOY_START_POINT_X, DEPLOY_START_POINT_Y);
                    foreach(PlayingPiece playingPieceToDeploy in listOfPlayingPiecesToDeploy)
                    {
                        if(playingPieceToDeploy is GroundSupportUnit)
                        {
                            Bitmap b = new Bitmap(PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                            Graphics g = Graphics.FromImage(b);
                            PlayingPieceGraphics.PaintGSU(g, (GroundSupportUnit)playingPieceToDeploy, new Point(PlayingPieceGraphics.GetBlockSize().Width / 2, PlayingPieceGraphics.GetBlockSize().Height / 2));
                            for (int i = 0; i < b.Width; i++)
                            {
                                for (int j = 0; j < b.Height; j++)
                                {
                                    if (b.GetPixel(i, j).A != 0)
                                    {
                                        b.SetPixel(i, j, Color.FromArgb(128, b.GetPixel(i, j)));
                                    }
                                }
                            }
                            e.Graphics.DrawImage(b, pointToDrawAt.X + currentHScroll, pointToDrawAt.Y + currentVScroll);
                            listPointsAtWhichPlayingPiecesToDeployAreShown.Add(pointToDrawAt);
                        }
                        else
                        {
                            Bitmap b = new Bitmap(PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                            Graphics g = Graphics.FromImage(b);
                            PlayingPieceGraphics.PaintBlock(g, (Block)playingPieceToDeploy, new Point(PlayingPieceGraphics.GetBlockSize().Width / 2, PlayingPieceGraphics.GetBlockSize().Height / 2), 1, false);
                            for (int i = 0; i < b.Width; i++)
                            {
                                for (int j = 0; j < b.Height; j++)
                                {
                                    if (b.GetPixel(i, j).A != 0)
                                    {
                                        b.SetPixel(i, j, Color.FromArgb(128, b.GetPixel(i, j)));
                                    }
                                }
                            }
                            e.Graphics.DrawImage(b, pointToDrawAt.X + currentHScroll, pointToDrawAt.Y + currentVScroll);
                            listPointsAtWhichPlayingPiecesToDeployAreShown.Add(pointToDrawAt);
                        }
                        pointToDrawAt.X += DEPLOY_START_POINT_GAP + PlayingPieceGraphics.GetBlockSize().Width;
                        if((pointToDrawAt.X + PlayingPieceGraphics.GetBlockSize().Width) > this.Size.Width)
                        {
                            pointToDrawAt.X = DEPLOY_START_POINT_X;
                            pointToDrawAt.Y += DEPLOY_START_POINT_GAP + PlayingPieceGraphics.GetBlockSize().Height;
                        }
                    }
                }
                #endregion

                #region Draw Special Actions
                if(currentDisplayMode != displayMode.AxisProduction)
                {
                    Point ptToDrawSAsIn;
                    int numGermanSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.Germany);
                    int numItalianSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.Italy);
                    int numBritishSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.GreatBritain);
                    int numFrenchSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.France);
                    int numUSSRSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.USSR);
                    int numUSASpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.USA);
                    int numPolishSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.Poland);
                    int numYugoslavSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.Yugoslavia);
                    int numSpanishSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.Spain);
                    int numTurkishSpecialActions = gameStateInfo.GetNumSpecialActions(MapInfo.CountryID.Turkey);
                    if (numGermanSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.Germany);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Germany, ptToDrawSAsIn);
                        e.Graphics.DrawString(numGermanSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numItalianSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.Italy);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Italy, ptToDrawSAsIn);
                        e.Graphics.DrawString(numItalianSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numBritishSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.GreatBritain);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.GreatBritain, ptToDrawSAsIn);
                        e.Graphics.DrawString(numBritishSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numFrenchSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.France);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.France, ptToDrawSAsIn);
                        e.Graphics.DrawString(numFrenchSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numUSSRSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.USSR);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.USSR, ptToDrawSAsIn);
                        e.Graphics.DrawString(numUSSRSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numUSASpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.USA);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.USA, ptToDrawSAsIn);
                        e.Graphics.DrawString(numUSASpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numPolishSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.Poland);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Poland, ptToDrawSAsIn);
                        e.Graphics.DrawString(numPolishSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numYugoslavSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.Yugoslavia);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Yugoslavia, ptToDrawSAsIn);
                        e.Graphics.DrawString(numYugoslavSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numSpanishSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.Spain);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Spain, ptToDrawSAsIn);
                        e.Graphics.DrawString(numSpanishSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                    if (numTurkishSpecialActions > 0)
                    {
                        ptToDrawSAsIn = UIRegion.GetUIPointForSpecialAction(MapInfo.CountryID.Turkey);
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Turkey, ptToDrawSAsIn);
                        e.Graphics.DrawString(numTurkishSpecialActions.ToString(), new Font("Arial", 25), new SolidBrush(Color.FromArgb(128, Color.Black)), new Point(ptToDrawSAsIn.X, ptToDrawSAsIn.Y + PlayingPieceGraphics.GetBlockSize().Height / 4));
                    }
                }
                #endregion

                if(gameStateInfo.GetAxisMinorStepMarker() != MapInfo.CountryID.Germany)
                {
                    MapInfo.RegionID capitalRegionID = MapInfo.GetCountryCapitalRegion(gameStateInfo.GetAxisMinorStepMarker());
                    UIRegion capitalUIRegion = europeEngulfedMapImage.GetUIRegion(capitalRegionID);
                    PlayingPieceGraphics.PaintAxisMinorStepMarker(e.Graphics, capitalUIRegion.PointCentre);
                }

                e.Graphics.Transform = new System.Drawing.Drawing2D.Matrix();

                #region Production Information
                if (currentDisplayMode == displayMode.AxisProduction)
                {
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.Germany, new Point((this.Width / 2) - 120, REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(currentGermanWERPProduction.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Red)), new Point((this.Width / 2) - 100, REMAININGWERPS_DISPLAY_Y1 - 20));
                    if(!gameStateInfo.IsNationConquered(MapInfo.CountryID.Italy))
                    {
                        PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.Italy, new Point((this.Width / 2), REMAININGWERPS_DISPLAY_Y1), true);
                        e.Graphics.DrawString(currentItalianWERPProduction.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Green)), new Point((this.Width / 2) + 20, REMAININGWERPS_DISPLAY_Y1 - 20));
                    }

                    PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Germany, new Point((this.Width / 2) - 120, REMAININGWERPS_DISPLAY_Y2));
                    e.Graphics.DrawString(currentGermanSpecialActions.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Red)), new Point((this.Width / 2) - 90, REMAININGWERPS_DISPLAY_Y2 - 20));
                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.Italy))
                    {
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.Italy, new Point((this.Width / 2), REMAININGWERPS_DISPLAY_Y2));
                        e.Graphics.DrawString(currentItalianSpecialActions.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Green)), new Point((this.Width / 2) + 30, REMAININGWERPS_DISPLAY_Y2 - 20));
                    }
                }
                else if (currentDisplayMode == displayMode.AlliedProduction)
                {
                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.GreatBritain))
                    {
                        PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.GreatBritain, new Point((this.Width / 2) - 120, REMAININGWERPS_DISPLAY_Y1), true);
                        e.Graphics.DrawString(currentUKWERPProduction.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Blue)), new Point((this.Width / 2) - 100, REMAININGWERPS_DISPLAY_Y1 - 20));
                    }
                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.France))
                    {
                        PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.France, new Point((this.Width / 2), REMAININGWERPS_DISPLAY_Y1), true);
                        e.Graphics.DrawString(currentFrenchWERPProduction.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.LightBlue)), new Point((this.Width / 2) + 20, REMAININGWERPS_DISPLAY_Y1 - 20));
                    }
                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.USSR) && gameStateInfo.GetCurrentGameDate() != GameTurn.GameDate.NovDev39)
                    {
                        PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.USSR, new Point((this.Width / 2) + 120, REMAININGWERPS_DISPLAY_Y1), true);
                        e.Graphics.DrawString(currentUSSRWERPProduction.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkRed)), new Point((this.Width / 2) + 140, REMAININGWERPS_DISPLAY_Y1 - 20));
                    }
                    if(gameStateInfo.IsNationAtWar(MapInfo.CountryID.USA))
                    {
                        PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.USA, new Point((this.Width / 2) + 240, REMAININGWERPS_DISPLAY_Y1), true);
                        e.Graphics.DrawString(currentUSWERPProduction.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkGreen)), new Point((this.Width / 2) + 280, REMAININGWERPS_DISPLAY_Y1 - 20));
                    }

                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.GreatBritain))
                    {
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.GreatBritain, new Point((this.Width / 2) - 120, REMAININGWERPS_DISPLAY_Y2));
                        e.Graphics.DrawString(currentUKSpecialActions.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Blue)), new Point((this.Width / 2) - 90, REMAININGWERPS_DISPLAY_Y2 - 20));
                    }
                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.France))
                    {
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.France, new Point((this.Width / 2), REMAININGWERPS_DISPLAY_Y2));
                        e.Graphics.DrawString(currentFrenchSpecialActions.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.LightBlue)), new Point((this.Width / 2) + 30, REMAININGWERPS_DISPLAY_Y2 - 20));
                    }
                    if (!gameStateInfo.IsNationConquered(MapInfo.CountryID.USSR))
                    {
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.USSR, new Point((this.Width / 2) + 120, REMAININGWERPS_DISPLAY_Y2));
                        e.Graphics.DrawString(currentUSSRSpecialActions.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkRed)), new Point((this.Width / 2) + 150, REMAININGWERPS_DISPLAY_Y2 - 20));
                    }
                    if (gameStateInfo.IsNationAtWar(MapInfo.CountryID.USA))
                    {
                        PlayingPieceGraphics.PaintTransparentSpecialActions(e.Graphics, MapInfo.CountryID.USA, new Point((this.Width / 2) + 240, REMAININGWERPS_DISPLAY_Y2));
                        e.Graphics.DrawString(currentUSSpecialActions.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkGreen)), new Point((this.Width / 2) + 270, REMAININGWERPS_DISPLAY_Y2 - 20));
                    }

                    if (currentUSSREmergencyConscription > 0)
                    {
                        e.Graphics.DrawString("Emergency Conscription: ", new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkRed)), new Point((this.Width / 2) - 180, REMAININGWERPS_DISPLAY_Y2 - 20 + 60));
                        e.Graphics.DrawString(currentUSSREmergencyConscription.ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkRed)), new Point((this.Width / 2) + 260, REMAININGWERPS_DISPLAY_Y2 - 20 + 60));
                    }
                }

                #endregion

                #region Strat Move Info
                if (currentDisplayMode == displayMode.AxisStratMove)
                {
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.Germany, new Point((this.Width / 2) - 120, REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(gameStateInfo.GetNumStratMovesForCountry(MapInfo.CountryID.Germany).ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Red)), new Point((this.Width / 2) - 100, REMAININGWERPS_DISPLAY_Y1 - 20));
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.Italy, new Point((this.Width / 2), REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(gameStateInfo.GetNumStratMovesForCountry(MapInfo.CountryID.Italy).ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Green)), new Point((this.Width / 2) + 20, REMAININGWERPS_DISPLAY_Y1 - 20));
                    if (gameStateInfo.GetGermanStratWarfareEffectOnStratMoves() > 0)
                        e.Graphics.DrawString("Strat Move Limited by Rail Interdiction: " + gameStateInfo.GetGermanStratWarfareEffectOnStratMoves().ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Red)), new Point((this.Width / 2) - 100, REMAININGWERPS_DISPLAY_Y2 - 20));
                    if (gameStateInfo.GetOperationOverlordEffect() > 0)
                        e.Graphics.DrawString("Strat Move Limited by Operation Overlord: " + gameStateInfo.GetOperationOverlordEffect().ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.Red)), new Point((this.Width / 2) - 100, REMAININGWERPS_DISPLAY_Y2 + 40));
                }
                else if (currentDisplayMode == displayMode.AlliedStratMove)
                {
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.GreatBritain, new Point((this.Width / 2) - 120, REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(gameStateInfo.GetNumStratMovesForCountry(MapInfo.CountryID.GreatBritain).ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkBlue)), new Point((this.Width / 2) - 100, REMAININGWERPS_DISPLAY_Y1 - 20));
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.France, new Point((this.Width / 2), REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(gameStateInfo.GetNumStratMovesForCountry(MapInfo.CountryID.France).ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.LightBlue)), new Point((this.Width / 2) + 20, REMAININGWERPS_DISPLAY_Y1 - 20));
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.USSR, new Point((this.Width / 2) + 120, REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(gameStateInfo.GetNumStratMovesForCountry(MapInfo.CountryID.USSR).ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkRed)), new Point((this.Width / 2) + 140, REMAININGWERPS_DISPLAY_Y1 - 20));
                    PlayingPieceGraphics.PaintControlMarker(e.Graphics, MapInfo.CountryID.USA, new Point((this.Width / 2) + 240, REMAININGWERPS_DISPLAY_Y1), true);
                    e.Graphics.DrawString(gameStateInfo.GetNumStratMovesForCountry(MapInfo.CountryID.USA).ToString(), new Font("Arial", 30), new SolidBrush(Color.FromArgb(100, Color.DarkGreen)), new Point((this.Width / 2) + 260, REMAININGWERPS_DISPLAY_Y1 - 20));

                    if (gameStateInfo.GetWAlliesStratWarfareEffectOnStratMoves() > 0)
                        e.Graphics.DrawString("Western Allied Strat Moves Limited by U-Boat Warfare: " + gameStateInfo.GetWAlliesStratWarfareEffectOnStratMoves().ToString(), new Font("Arial", 20), new SolidBrush(Color.FromArgb(100, Color.DarkBlue)), new Point((this.Width / 2) - 350, REMAININGWERPS_DISPLAY_Y2 - 20));
                }
                #endregion

                if(fadingMessages.Count > 0)
                {
                    int heightPosition = 5;
                    foreach(FadingMessage fadingMessage in fadingMessages)
                    {
                        if(fadingMessage.messageType == fadingMessageType.rules)
                            fadingMessageBrush.Color = Color.FromArgb(fadingMessage.fadingMessageAlpha, Color.DarkRed);
                        else if(fadingMessage.messageType == fadingMessageType.networkmessage)
                            fadingMessageBrush.Color = Color.FromArgb(fadingMessage.fadingMessageAlpha, Color.DarkGreen);
                        e.Graphics.DrawString(fadingMessage.message, fadingMessageFont, fadingMessageBrush, new RectangleF(5, heightPosition, this.Width - 5, fadingMessageFont.Height));
                        heightPosition += fadingMessageFont.Height;
                    }
                }
            }

            //////////////////////////////////////////
        }

        public void ZoomIn()
        {
            ScaleLevel++;
        }

        public void ZoomOut()
        {
            ScaleLevel--;
        }

        public UIRegion GetUIRegionClicked(int mouseX, int mouseY)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = {new System.Drawing.Point(mouseX,mouseY)};
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
  
            return this.europeEngulfedMapImage.GetUIRegion(mousePoint[0].X, mousePoint[0].Y);
        }

        public void IncrementUIBlockIndex(int mouseX, int mouseY, bool bDecrement)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mouseX, mouseY) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);

            List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(blockHilightRegionID);
            List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(blockHilightRegionID);

            this.europeEngulfedMapImage.SetBlockDisplayIndex(mousePoint[0], PlayingPieceGraphics.GetBlockSize(), alliedBlockList, axisBlockList, bDecrement);
            this.Invalidate(); //TODO Look at just invalidating the required rectangle
        }

        public void IncrementUIGSUIndex(int mouseX, int mouseY, bool bDecrement)
        {
            MapInfo.RegionID gsuRegion = MapInfo.RegionID.Alexandria;
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mouseX, mouseY) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);

            if(this.europeEngulfedMapImage.IsMouseOverRegion(ref gsuRegion, mousePoint[0]))
            {
                if(MapInfo.IsLandRegion(gsuRegion))
                {
                    List<GroundSupportUnit> alliedGSUList = gameStateInfo.GetRegionsAlliedGSUList(gsuRegion);
                    List<GroundSupportUnit> axisGSUList = gameStateInfo.GetRegionsAxisGSUList(gsuRegion);
                    List<Block> alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(gsuRegion);
                    List<Block> axisBlockList = gameStateInfo.GetRegionsAxisBlockList(gsuRegion);

                    this.europeEngulfedMapImage.SetGSUDisplayIndex(mousePoint[0], PlayingPieceGraphics.GetGSUSize(), alliedGSUList, axisGSUList, alliedBlockList, axisBlockList, bDecrement);
                    this.Invalidate(); //TODO Look at just invalidating the required rectangle
                }
            }
        }

        public void SetBlockHilight(int mouseX, int mouseY)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(mouseX, mouseY) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);
            List<Block> alliedBlockList;
            List<Block> axisBlockList;

            if (this.europeEngulfedMapImage.IsMouseOverCentredBlocks(ref blockHilightRegionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize()))
            {
                alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(blockHilightRegionID);
                axisBlockList = gameStateInfo.GetRegionsAxisBlockList(blockHilightRegionID);

                if (((alliedBlockList.Count != 2 && alliedBlockList.Count > 0) && axisBlockList.Count == 0) || (alliedBlockList.Count == 0 && (axisBlockList.Count != 2 && axisBlockList.Count > 0)))
                {
                    blockHighlight = blockHighlightType.Centre;
                    return;
                }
            }
            
            if (this.europeEngulfedMapImage.IsMouseOverContestedBlocks1(ref blockHilightRegionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize()))
            {
                alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(blockHilightRegionID);
                axisBlockList = gameStateInfo.GetRegionsAxisBlockList(blockHilightRegionID);

                if (alliedBlockList.Count == 2 || axisBlockList.Count == 2 || (axisBlockList.Count > 0 && alliedBlockList.Count > 0))
                {
                    blockHighlight = blockHighlightType.Allied;
                    return;
                }
            }

            if (this.europeEngulfedMapImage.IsMouseOverContestedBlocks2(ref blockHilightRegionID, mousePoint[0], PlayingPieceGraphics.GetBlockSize()))
            {
                alliedBlockList = gameStateInfo.GetRegionsAlliedBlockList(blockHilightRegionID);
                axisBlockList = gameStateInfo.GetRegionsAxisBlockList(blockHilightRegionID);

                if (alliedBlockList.Count == 2 || axisBlockList.Count == 2 || (axisBlockList.Count > 0 && alliedBlockList.Count > 0))
                    blockHighlight = blockHighlightType.Axis;
            }

            this.Invalidate();
        }

        public void UnSetBlockHilight()
        {
            blockHighlight = blockHighlightType.None;
            this.Invalidate();
        }

        private struct GameDateInfo
        {
            public GameTurn.GameDate gameDate;
            public string info;
            public GameDateInfo(GameTurn.GameDate gameDate, string info)
            {
                this.info = info;
                this.gameDate = gameDate;
            }
        };

        private GameDateInfo[] gameDateInfoTable =
            {
                new GameDateInfo(GameTurn.GameDate.SepOct39, "Start 39 Campaign Game\nNo Power Produces This Turn"),
                new GameDateInfo(GameTurn.GameDate.NovDev39, "Soviets(Only) may not produce this turn\nNo Axis Fleets Built This Turn"),
                new GameDateInfo(GameTurn.GameDate.JanFeb40, "German Force Pool Adds\nSoviet Production To 9 WERPs"),
                new GameDateInfo(GameTurn.GameDate.MarApr40, "Phony War Restrictions Lifted"),
                new GameDateInfo(GameTurn.GameDate.JanFeb41, "German Force Pool Adds\nSoviet Production To 17 WERPs"),
                new GameDateInfo(GameTurn.GameDate.MarApr41, "Polish Garrison to minimum of 10 units"),
                new GameDateInfo(GameTurn.GameDate.JulAug41, "Start 41 Campaign"),
                new GameDateInfo(GameTurn.GameDate.JanFeb42, "USA Enters War\nGerman/Soviet/British Force Pool Adds\nRemove 5th German Special Action\nAxis Infantry in USSR Freezes\nUSSR May Declare War"),
                new GameDateInfo(GameTurn.GameDate.JulAug42, "Western Allies May Declare War On Vichy"),
                new GameDateInfo(GameTurn.GameDate.JanFeb43, "German/Soviet/British/US Force Pool Adds\nAdd 2nd Soviet And US Special Actions\nSoviet Cadre Bonus Ends\nWestern Allied Bomber Point Upgraded"),
                new GameDateInfo(GameTurn.GameDate.JanFeb44, "German/Soviet/British/US Force Pool Adds\nRemove 4th German Special Action\nAdd 3nd Soviet And US Special Actions\nBritish Ground Unit Step Cost Increase\nWestern Allied Fighter Points Upgraded\nV1 Points May Be Purchased"),
                new GameDateInfo(GameTurn.GameDate.MayJun44, "Last Turn For Allied Decisive Victory"),
                new GameDateInfo(GameTurn.GameDate.SepOct44, "V2 Points May Be Purchased"),
                new GameDateInfo(GameTurn.GameDate.NovDec44, "Last Turn For Allied Operational Victory"),
                new GameDateInfo(GameTurn.GameDate.JanFeb45, "Soviet Force Pool Add\nSoviet Ground Unit Step Costs Increase(If Conscription was taken)"),
                new GameDateInfo(GameTurn.GameDate.MayJun45, "Last Turn For Allied Marginal Victory"),
                new GameDateInfo(GameTurn.GameDate.NovDec45, "End Campaign Game\nLast Turn For A Draw"),
            };

        public string GetGameDateInfoAtPoint(Point ptPoint)
        {
            System.Drawing.Drawing2D.Matrix clickTransform = europeEngulfedMapTransform.Clone();
            System.Drawing.Point[] mousePoint = { new System.Drawing.Point(ptPoint.X, ptPoint.Y) };
            clickTransform.Invert();
            clickTransform.TransformPoints(mousePoint);

            GameTurn.GameDate gameDate = GameTurn.GameDate.NovDev39;
            if (this.europeEngulfedMapImage.GetGameDateAtPoint(ref gameDate, mousePoint[0]))
            {
                string stringToReturn = GameTurn.GameDateToString(gameDate);
                foreach(GameDateInfo gameDateInfo in gameDateInfoTable)
                {
                    if(gameDateInfo.gameDate == gameDate)
                    {
                        stringToReturn += "\n";
                        stringToReturn += gameDateInfo.info;
                        return stringToReturn;
                    }
                }
                return stringToReturn;
            }

            return "";
        }
    }
}
